package cn.memset.code.parallel;

import cn.memset.code.stream.Employee;
import cn.memset.code.stream.Utils;

import java.util.*;
import java.util.stream.Collectors;

public class ParallelExample {
    public static void main(String[] args) {
        safeParallelOperation();
    }

    public static void groupEmployeesToMap() {
        List<Employee> employees = Utils.makeEmployees();
        Map<String, List<Employee>> map = employees.parallelStream()
                .collect(Collectors.groupingBy(Employee::getDepartment));
        System.out.println(map);
    }

    public static void unsafeParallelOperation() {
        List<String> provinces = Arrays.asList("Guangdong", "Jiangsu", "Guangxi", "Jiangxi", "Shandong");

        // "副作用" 导致的线程不安全问题
        ArrayList<String> results = new ArrayList<>();
        provinces.parallelStream()
                // 过滤掉以 G 开头的省份
                .filter(s -> !s.startsWith("G"))
                // 在 lambda表达式中修改了 results 的值，
                // 说明了 "s -> results.add(s)" 并非一个纯函数，
                // 带来了不必要的 "副作用"，
                // 在并行执行时，会导致线程不安全的问题。
                .forEach(s -> results.add(s));

        System.out.println(results);
    }

    public static void safeParallelOperation() {
        List<String> provinces = Arrays.asList("Guangdong", "Jiangsu", "Guangxi", "Jiangxi", "Shandong");

        List<String> results = provinces.parallelStream()
                // 过滤掉以 G 开头的省份
                .filter(s -> !s.startsWith("G"))
                // 没有 "副作用"
                .collect(Collectors.toList());

        System.out.println(results);
    }
}
